from django.contrib.auth import login, logout
from account import serializers
from account.models import User, Classify, Tag, Fans, Collect, Avatar
from article.models import Article
from utils import exceptions
from utils.image_code import ImageCode
from utils.base_api_view import BaseAPIView
from utils.permissions import IsLogin, IsAdmin
from utils.upload import write_file_local, delete_old_file
from django_redis import get_redis_connection


class LoginAPI(BaseAPIView):
    serializer_classes = serializers.LoginSeralizer

    def __init__(self):
        super().__init__()
        self.uuid_code = ''
        self.conn = get_redis_connection('verify_code')

    def post(self, request, *args, **kwargs):
        data = self.post_serializer_data()
        username = data.get('username')
        password = data.get('password')
        verify_code = data.get('verify_code')
        self.uuid_code = data.get('uuid')
        image_code = self.conn.get(f'img_code_{self.uuid_code}')
        if image_code is not None and verify_code.lower() != image_code.decode().lower():
            raise exceptions.InvalidVerifyCode()
        if str(username).find('@') != -1:
            user = User.objects.filter(email=username).first()
            if user:
                return self.login_in(user, password)
        if username.startswith('1') and len(username) == 11:
            user = User.objects.filter(phone_number=username).first()
            if user:
                return self.login_in(user, password)
        user = User.objects.filter(username=username).first()
        if user:
            return self.login_in(user, password)
        else:
            raise exceptions.UserNotFind()

    def login_in(self, user, password):
        if user.check_password(password):
            login(self.request, user)
            self.request.session.set_expiry(60 * 60 * 24 * 2)
            self.clear_image_code()
            return self.succeed(
                message='登陆成功',
                data={
                    'username': user.username
                }
            )
        raise exceptions.WrongPassword()

    def clear_image_code(self):
        # 删除不存在的键不会报错
        self.conn.delete(f'img_code_{self.uuid_code}')


class LogOut(BaseAPIView):
    permission_classes = [IsLogin]

    def get(self, request, *args, **kwargs):
        logout(request)
        return self.succeed('登出成功')


class RegisterAPI(BaseAPIView):
    serializer_classes = serializers.RegisterSerializer

    def post(self, request, *args, **kwargs):
        data = self.post_serializer_data()
        username = data.get('username')
        password = data.get('password')
        phone = data.get('phone_number')
        email = data.get('email')
        is_admin = data.get('is_admin')
        if User.objects.filter(username=username).exists():
            return self.error('用户名重复')
        if phone is not None:
            if User.objects.filter(phone_number=phone).exists():
                return self.error('手机号码重复')
        if email is not None:
            if User.objects.filter(email=email).exists():
                return self.error('邮箱重复')
        if is_admin:
            user = User.objects.create_superuser(username, password, phone, email)
        else:
            user = User.objects.create_user(username, password, phone, email)
        if user:
            return self.succeed('用户创建成功')
        else:
            return self.error('用户创建失败')


class ChangePassword(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.ChangePasswordSerializer

    def post(self, request, *args, **kwargs):
        user = request.user
        data = self.post_serializer_data()
        old_pass = data.get('old_pass')
        new_pass = data.get('new_pass')
        if user.check_password(old_pass):
            user.set_password(new_pass)
            user.save()
            return self.succeed('修改成功')
        else:
            self.error('原密码错误')


class UserInfo(BaseAPIView):
    serializer_classes = serializers.UserInfoSerializer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('user_name')
        user = None
        if username:
            if User.objects.filter(username=username).exists():
                user = User.objects.filter(username=username).first()
        elif not request.user.is_anonymous:
            user = request.user
        else:
            self.error('找不到该用户')
        data = self.serializer_out(user)
        return self.succeed(data=data)


class UpdateUserInfo(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.UpdateUserInfoSeralizer

    def __init__(self):
        super().__init__()
        self.data = {}

    def check_unique(self):
        username = self.data.get('username', None)
        email = self.data.get('email', None)
        phone_number = self.data.get('phone_number', None)
        if username:
            if User.objects.filter(username=username).exists():
                self.error(f'已经存在名为"{username}"的用户')
        if email:
            if User.objects.filter(email=email).exists():
                self.error(f'已经存在邮件为"{email}"的用户')
        if phone_number:
            if User.objects.filter(phone_number=phone_number).exists():
                self.error(f'已经存在手机号为"{phone_number}"的用户')

    def post(self, request, *args, **kwargs):
        self.data = self.post_serializer_data()
        self.check_unique()
        row = User.objects.filter(id=request.user.id).update(**self.data)
        if row == 1:
            return self.succeed('修改成功')
        self.error('修改失败')


class UploadAvatar(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.UploadAvatarSeralizer

    def delete_old_avatar(self):
        if Avatar.objects.filter(user_id=self.request.user.id).exists():
            avatar_url = Avatar.objects.filter(user_id=self.request.user.id).first().avatar_url
            file_name = avatar_url.split('/')[-1]
            delete_old_file('./upload/avatar/' + file_name)

    def post(self, request, *args, **kwargs):
        # user_id = request.user.id
        file = self.post_serializer_data().get('file')
        file_type = file.content_type.split('/')[1]
        file_type = 'jpg' if file_type == 'jpeg' else file_type
        if file_type.lower() not in ['jpg', 'png']:
            raise self.error('上传失败！图片格式不正确')
        file_name = write_file_local(file, file_type, catalog='avatar/')
        self.delete_old_avatar()
        if file_name:
            avatar_url = 'http://127.0.0.1:8000/file/avatar/' + file_name
            avatar, created = Avatar.objects.update_or_create(
                user=request.user,
                defaults={'avatar_url': avatar_url}
            )
            if avatar or created:
                return self.succeed(data={
                    'avatar_url': avatar_url,
                })
        raise self.error('上传失败')


class CreateClassify(BaseAPIView):
    permission_classes = [IsAdmin]

    def post(self, request, *args, **kwargs):
        classify_name = request.data.get('classify', None)
        if classify_name:
            if Classify.objects.filter(classify_name=classify_name).exists():
                self.error('当前标签已存在')
            classify = Classify.objects.create(
                classify_name=classify_name,
                admin=request.user
            )
            if classify:
                return self.succeed('创建成功')
            else:
                self.error('创建失败')
        else:
            self.error('缺少参数')


class ListClassify(BaseAPIView):
    serializer_classes = serializers.ListClassifySerializer

    def get(self, request, *args, **kwargs):
        queryset = Classify.objects.all()
        data = self.serializer_out(queryset, True)
        return self.succeed(data=data)


class CreateTag(BaseAPIView):
    permission_classes = [IsLogin]

    def post(self, request, *args, **kwargs):
        tag_name = request.data.get('tag', None)
        user = request.user
        if tag_name:
            # 使用 user_id 来查询和更改表数据正常
            if Tag.objects.filter(tag_name=tag_name, user=user).exists():
                return self.succeed('该标签已存在')
            tag = Tag.objects.create(
                tag_name=tag_name,
                user=user
            )
            if tag:
                return self.succeed('创建成功')
            else:
                self.error('创建失败')
        else:
            self.error('缺少参数')


class ListTags(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.ListTagSerializer

    def get(self, request, *args, **kwargs):
        user_id = request.user.id
        tag_name_contains = self.get_serializer_data().get('tag_name_contains')
        queryset = Tag.objects.filter(user_id=user_id)
        if tag_name_contains:
            queryset = queryset.filter(tag_name__contains=tag_name_contains)
        return self.pagination_with_serializer(queryset.order_by('id'))


class DeleteTags(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.DeleteTagsSerializer

    def get(self, request, *args, **kwargs):
        tag_ids = self.get_serializer_data().get('ids')
        user_id = request.user.id
        result, obj = Tag.objects.filter(id__in=tag_ids, user_id=user_id).delete()
        if result > 0:
            return self.succeed('删除成功')
        else:
            self.error('删除失败')


class ModifyTag(BaseAPIView):
    permission_classes = [IsLogin]

    def post(self, request, *args, **kwargs):
        tag_id = request.data.get('id', None)
        tag_name = request.data.get('tag_name', None)
        if not tag_id and not tag_name:
            raise exceptions.ParamError()
        if Tag.objects.filter(id=tag_id, user_id=request.user.id).exists():
            row = Tag.objects.filter(id=tag_id).update(tag_name=tag_name)
            if row:
                return self.succeed('修改成功')
            else:
                self.error('修改失败')
        else:
            raise exceptions.PermissionDenied()


class AttentionUser(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.AttentionUserSerializer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('username')
        if User.objects.filter(username=username).exists():
            attention_user = User.objects.filter(username=username).first()
            user = request.user
            fan, created = Fans.objects.update_or_create(
                user=user, attention_user=attention_user,
                defaults={'is_delete': False}
            )
            if fan:
                return self.succeed('关注成功')
            else:
                self.error('关注失败')
        else:
            self.error('没有查询到此用户')


class CancelAttentionUser(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.CancelAttentionSerializer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('username')
        if User.objects.filter(username=username).exists():
            user = User.objects.filter(username=username).first()
            row = Fans.objects.filter(attention_user=user, user_id=request.user).update(is_delete=True)
            if row > 0:
                return self.succeed('取消关注成功')
            else:
                self.error('取消关注失败')
        self.error('没有查询到相关用户')


# 检查当前用户是否关注了传入的用户
class CheckAttentionInfo(BaseAPIView):
    serializer_classes = serializers.CheckAttentionInfoSerializer

    def get(self, request, *args, **kwargs):
        if request.user.is_anonymous:
            return self.succeed(data={
                'stared': False
            })
        username = self.get_serializer_data().get('username')
        if User.objects.filter(username=username).exists():
            # user_id = User.objects.filter(username=username).first().id
            user = User.objects.filter(username=username).first()
            # if Fans.objects.filter(user_id=request.user.id, attention_id=user_id, is_delete=False).exists():
            if request.user.attentions.filter(attention_user=user, is_delete=False).exists():
                stared = True
            else:
                stared = False
            return self.succeed(data={
                'stared': stared
            })
        self.error('没有查询到该用户')


class ListAttentionUser(BaseAPIView):
    serializer_classes = serializers.ListAttentionUserSerializer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('user_name')
        user = None
        if username:
            if User.objects.filter(username=username).exists():
                user = User.objects.filter(username=username).first()
        elif not request.user.is_anonymous:
            user = request.user
        else:
            self.error('找不到该用户')
        attention_user_ids = user.attentions.filter(is_delete=False).values_list('attention_user', flat=True)
        users = User.objects.filter(id__in=attention_user_ids)
        data = self.serializer_out(users, many=True)
        return self.succeed(data=data)


class CollectArticle(BaseAPIView):
    permission_classes = [IsLogin]

    def get(self, request, *args, **kwargs):
        article_id = request.GET.get('article_id', None)
        if article_id:
            if not Article.objects.filter(id=article_id).exists():
                self.error('没有找到改文章')
            user_id = request.user.id
            collect, created = Collect.objects.update_or_create(
                user_id=user_id, article_id=article_id,
                defaults={'is_delete': False}
            )
            if collect:
                return self.succeed('收藏成功')
            else:
                self.error('收藏失败')
        else:
            raise exceptions.ParamError()


class CancelCollectArticle(BaseAPIView):
    permission_classes = [IsLogin]
    serializer_classes = serializers.CancelCollectArticleSerializer

    def get(self, request, *args, **kwargs):
        article_ids = self.get_serializer_data().get('ids')
        row = request.user.collects.filter(article__in=article_ids).update(is_delete=True)
        if row > 0:
            return self.succeed('取消收藏成功')
        else:
            self.error('取消收藏失败')


class ListCollectArticle(BaseAPIView):
    serializer_classes = serializers.ListCollectArticleSeralizer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('username')
        if User.objects.filter(username=username).exists():
            user = User.objects.filter(username=username).first()
        else:
            if request.user.is_anonymous:
                self.error('没有指定查找的用户')
            user = request.user
        article_ids = user.collects.filter(is_delete=False).values_list('article', flat=True)
        # 倒序排数数据重复
        articles = Article.objects.filter(id__in=article_ids).order_by('by_collect__collect_date')
        return self.pagination_with_serializer(articles)


class FansCount(BaseAPIView):
    serializer_classes = serializers.FansCountSerialzer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('username')
        if User.objects.filter(username=username).exists():
            user = User.objects.filter(username=username).first()
            fans_count = user.by_attention.count()
            return self.succeed(data={
                'fans_count': fans_count
            })
        else:
            self.error()


# 文章总数 没用到
class ArticleCount(BaseAPIView):
    serializer_classes = serializers.ArticleCountSerialzer

    def get(self, request, *args, **kwargs):
        username = self.get_serializer_data().get('username')
        article_count = Article.objects.filter(author=username).count()
        return self.succeed(data={
            'article_count': article_count
        })


class ImageCodeAPI(BaseAPIView):
    def get(self, request, *args, **kwargs):
        uuid = kwargs.get('uuid')
        # img = ImageCode.generate_image_code(uuid)
        img = ImageCode.generate_image_by_captcha(uuid)
        return self.image_response(img)
